#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>

/**
 * 存储映射 到内存
 * @return
 */
//int main() {
//    int fd = -1;
//    int ret = -1;
//    void * addr = NULL;
//    //打开文件
//    fd = open("storagemapping",O_RDWR);
//    if(-1 == fd){
//        perror("open");
//        return 1;
//    }
//    //文件映射到内存
//    addr = mmap(NULL,1024,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
//    if(addr == MAP_FAILED){
//        perror("mmap");
//        return 1;
//    }
//    printf("文件存储映射完成！\n");
//    //关闭文件
//    close(fd);
//    //写文件
//    memcpy(addr,"1234567890",10);
//    //断开映射
//    munmap(addr,1024);
//
//    return 0;
//}

/**
 * 存储映射 被父子进程使用
 * @return
 */
//int main() {
//    int fd = -1;
//    int ret = -1;
//    pid_t pid = -1;
//    void * addr = NULL;
//    //打开文件
//    fd = open("storagemapping",O_RDWR);
//    if(-1 == fd){
//        perror("open");
//        return 1;
//    }
//    //文件映射到内存
//    addr = mmap(NULL,1024,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
//    if(addr == MAP_FAILED){
//        perror("mmap");
//        return 1;
//    }
//    printf("文件存储映射完成！\n");
//    //关闭文件
//    close(fd);
//    //创建进程
//    pid = fork();
//    if(-1 == pid){
//        perror("fork");
//        return 1;
//    }
//    //子进程
//    if(0 == pid){
//        //写文件 文件中必须要有数据，否则报错  总线错误 (核心已转储)
//        memcpy(addr,"1234567890", 10);
//        printf("子进程\n");
//    }
//    //父进程
//    else{
//        printf("父进程\n");
//        wait(NULL);
//        printf("父进程读取 : %s\n",(char *) addr);
//    }
//    //断开映射
//    munmap(addr,1024);
//
//    return 0;
//}

/**
 * 匿名存储映射 只能在父子进程之间使用
 * @return
 */
int main() {
    int ret = -1;
    pid_t pid = -1;
    void * addr = NULL;
    //创建匿名映射
    addr = mmap(NULL,4096,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0);
    if(addr == MAP_FAILED){
        perror("mmap");
        return 1;
    }
    //创建子进程
    pid = fork();
    if(-1 == pid){
        perror("fork");
        munmap(addr,4096);
        return 1;
    }
    //子进程
    if(0 == pid){
        //写文件 文件中必须要有数据，否则报错  总线错误 (核心已转储)
        memcpy(addr,"1234567890", 10);
        printf("子进程\n");
    }
    //父进程
    else{
        printf("父进程\n");
        wait(NULL);
        printf("父进程读取 : %s\n",(char *) addr);
    }

    //断开映射
    munmap(addr,4096);

    return 0;
}